package lin.an.user.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.PhoneUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lin.an.enums.BuildInEnum;
import lin.an.enums.CommonSortOrderEnum;
import lin.an.enums.StatusEnum;
import lin.an.exception.CommonException;
import lin.an.food.entity.Food;
import lin.an.food.entity.FoodFavorite;
import lin.an.food.param.FoodPageParam;
import lin.an.food.service.FoodFavoriteService;
import lin.an.food.service.FoodService;
import lin.an.pojo.CommonPageRequest;
import lin.an.user.Param.*;
import lin.an.user.entity.User;
import lin.an.user.mapper.UserMapper;
import lin.an.user.service.UserService;
import lin.an.util.CommonAvatarUtil;
import lin.an.util.CommonCryptogramUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author zhoulinq
 * @date 2025/3/10
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Autowired
    private FoodFavoriteService foodFavoriteService;
    @Autowired
    private FoodService foodService;
    /**
     * 新增用户
     * @param userAddParam
     */
    @Override
    @Transactional(rollbackFor = {java.lang.Exception.class})
    public void add(UserAddParam userAddParam) {
        checkParam(userAddParam);
        User user = BeanUtil.toBean(userAddParam, User.class);
        if(ObjectUtil.isEmpty(user.getAvatar())) {
            // 设置默认头像
            user.setAvatar(CommonAvatarUtil.generateImg(user.getUserName()));
        }
        // 设置密码(加密方法Sm4)
        user.setPassword(CommonCryptogramUtil.doSm4Encrypt(user.getPassword()));
        //  设置用户角色名（管理员或普通用户）
        user.setRoleName("普通用户");
        // 设置状态
        user.setStatus(StatusEnum.ENABLE.getValue());
        this.save(user);
    }

    /**
     * 删除用户
     */
    @Transactional(rollbackFor = {java.lang.Exception.class})
    @Override
    public void detele(List<UserDeleteParam> userDeleteParamList) {
        List<String> userIdList = CollStreamUtil.toList(userDeleteParamList, UserDeleteParam::getUserId);
        if(ObjectUtil.isNotEmpty(userIdList)) {
            boolean containsSuperAdminAccount = this.listByIds(userIdList).stream().map(User::getAccount)
                    .collect(Collectors.toSet()).contains(BuildInEnum.BUILD_IN_USER_ACCOUNT.getValue());
            if(containsSuperAdminAccount) {
                throw new CommonException("不可删除系统内置超管人员");
            }
        }
        // 执行删除
        this.removeByIds(userIdList);
    }

    /**
     * 修改人员
     */
    @Override
    @Transactional(rollbackFor = {java.lang.Exception.class})
    public void edit(UserEditParam userEditParam) {
        User user = this.getById(userEditParam.getUserId());
        if(ObjectUtil.isEmpty(user)){
            throw new CommonException("人员不存在，id值为：{}", userEditParam.getUserId());
        }
        checkParam(userEditParam);
        boolean updateSuperAdminAccount = user.getAccount().equals(BuildInEnum.BUILD_IN_USER_ACCOUNT.getValue()) &&
                !userEditParam.getAccount().equals(BuildInEnum.BUILD_IN_USER_ACCOUNT.getValue());
        if(updateSuperAdminAccount) {
            throw new CommonException("不可修改系统内置超管人员账号");
        }
        BeanUtil.copyProperties(userEditParam, user);
        this.updateById(user);
    }

    @Override
    public Page<User> page(UserPageParam userPageParam) {
        Page<User> page = new Page<>(userPageParam.getPage(), userPageParam.getSize());
        QueryWrapper<User> queryWrapper = new QueryWrapper<User>().checkSqlInjection();
        if (ObjectUtil.isAllNotEmpty(userPageParam.getSortField(), userPageParam.getSortOrder())) {
            CommonSortOrderEnum.validate(userPageParam.getSortOrder());
            queryWrapper.orderBy(true, userPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
                    StrUtil.toUnderlineCase(userPageParam.getSortField()));
        }
        return this.page(page, queryWrapper);
    }

    /**
     * 模糊查询用户
     * @param userLikeParam
     */
    @Override
    public List<User> like(UserLikeParam userLikeParam) {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        if (ObjectUtil.isNotEmpty(userLikeParam.getUserName())){
            lambdaQueryWrapper.like(User::getUserName,userLikeParam.getUserName());
        }
        List<User> userList = this.list(lambdaQueryWrapper);
        if(userList == null){
            throw new CommonException("未查询到符合条件的用户");
        }
        return userList;
    }

    @Override
    public User detailOne() {
        int userId = StpUtil.getLoginIdAsInt();
        return this.getById(userId);
    }

    /**
     * 获取用户收藏的美食列表
     */
    @Override
    public List<Food> favoriteList() {
        // 获取当前登录用户的ID
        int userId = StpUtil.getLoginIdAsInt();
        
        // 构建查询条件，查询food_favorite表中的food_id字段
        LambdaQueryWrapper<FoodFavorite> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FoodFavorite::getUserId, userId)
                   .select(FoodFavorite::getFoodId);  // 只查询food_id字段
        
        // 获取用户收藏的美食ID列表
        List<Integer> favoriteFoodIds = foodFavoriteService.list(queryWrapper)
                .stream()
                .map(FoodFavorite::getFoodId)
                .collect(Collectors.toList());
        
        // 如果没有收藏的美食，返回空列表
        if (ObjectUtil.isEmpty(favoriteFoodIds)) {
            return List.of();
        }
        
        // 获取收藏的美食详情
        List<Food> favoriteFoods = foodService.favoriteFood(favoriteFoodIds);
        
        // 如果获取到的美食列表为空，返回空列表
        if (ObjectUtil.isEmpty(favoriteFoods)) {
            return List.of();
        }
        
        return favoriteFoods;
    }

    /**
     * 找回密码
     */
    @Override
    public String resetPassWord(UserResetParam userResetParam) {
        // 参数校验
        if (ObjectUtil.hasEmpty(userResetParam.getUserName(), userResetParam.getAccount(), 
            userResetParam.getNewPassword(), userResetParam.getPhone(), 
            userResetParam.getGender(), userResetParam.getAge())) {
            throw new CommonException("所有字段都不能为空");
        }

        // 验证手机号格式
        if (!PhoneUtil.isMobile(userResetParam.getPhone())) {
            throw new CommonException("手机号码格式错误");
        }

        // 根据账号查询用户
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getAccount, userResetParam.getAccount());
        User user = this.getOne(lambdaQueryWrapper);

        if (ObjectUtil.isEmpty(user)) {
            throw new CommonException("账号不存在");
        }

        // 验证其他信息是否匹配
        if (!user.getUserName().equals(userResetParam.getUserName())) {
            throw new CommonException("用户名不匹配");
        }
        if (!user.getPhone().equals(userResetParam.getPhone())) {
            throw new CommonException("手机号不匹配");
        }
        if (!user.getGender().equals(userResetParam.getGender())) {
            throw new CommonException("性别不匹配");
        }
        if (!user.getAge().equals(userResetParam.getAge())) {
            throw new CommonException("年龄不匹配");
        }

        // 所有信息验证通过，更新密码
        user.setPassword(CommonCryptogramUtil.doSm4Encrypt(userResetParam.getNewPassword()));
        this.updateById(user);
        return "密码重置成功";
    }

    /**
     * 获取总用户数
     */
    @Override
    public Long amount() {
        return this.count();
    }

    /**
     * 封禁用户
     */
    @Override
    @Transactional(rollbackFor = {java.lang.Exception.class})
    public void banUser(Integer userId) {
        User user = this.getById(userId);
        if(ObjectUtil.isEmpty(user)) {
            throw new CommonException("用户不存在，id值为：{}", userId);
        }
        // 检查是否为超级管理员
        if(user.getAccount().equals(BuildInEnum.BUILD_IN_USER_ACCOUNT.getValue())) {
            throw new CommonException("不可封禁系统内置超管人员");
        }
        // 设置状态为禁用
        user.setStatus(StatusEnum.DISABLED.getValue());
        this.updateById(user);
    }

    /**
     * 解封用户
     */
    @Override
    @Transactional(rollbackFor = {java.lang.Exception.class})
    public void unbanUser(Integer userId) {
        User user = this.getById(userId);
        if(ObjectUtil.isEmpty(user)) {
            throw new CommonException("用户不存在，id值为：{}", userId);
        }
        // 设置状态为启用
        user.setStatus(StatusEnum.ENABLE.getValue());
        this.updateById(user);
    }

    private void checkParam(UserAddParam userAddParam){
        if (this.count(new LambdaQueryWrapper<User>()
                .eq(User::getAccount, userAddParam.getAccount())) > 0) {
            throw new CommonException("存在重复的账号，账号为：{}", userAddParam.getAccount());
        }
        if(ObjectUtil.isNotEmpty(userAddParam.getPhone())) {
            if(!PhoneUtil.isMobile(userAddParam.getPhone())) {
                throw new CommonException("手机号码：{}格式错误", userAddParam.getPhone());
            }
            if (this.count(new LambdaQueryWrapper<User>()
                    .eq(User::getPhone,userAddParam.getPhone())) > 0) {
                throw new CommonException("存在重复的手机号，手机号为：{}", userAddParam.getPhone());
            }
        }
    }
    private void checkParam(UserEditParam userEditParam){
        if(ObjectUtil.isNotEmpty(userEditParam.getPhone())) {
            if(!PhoneUtil.isMobile(userEditParam.getPhone())) {
                throw new CommonException("手机号码：{}格式错误", userEditParam.getPhone());
            }
        }
    }
}
